package com.ruoyi.plus.pub.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.plus.pub.domain.PubResourcesClass;
import com.ruoyi.plus.pub.mapper.PubResourcesClassMapper;
import com.ruoyi.plus.pub.service.IPubResourcesClassService;
import com.ruoyi.plus.utils.TreeBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 资源分类管理Service业务层处理
 */
@Service
public class PubResourcesClassServiceImpl extends ServiceImpl<PubResourcesClassMapper, PubResourcesClass> implements IPubResourcesClassService {

    @Autowired
    private PubResourcesClassMapper pubResourcesClassMapper;

    /**
     * 查询资源分类管理列表
     *
     * @param pubResourcesClass 资源分类管理
     * @return 资源分类管理
     */
    @Override
    public List<PubResourcesClass> selectPubResourcesClassList(PubResourcesClass pubResourcesClass) {
        return pubResourcesClassMapper.selectPubResourcesClassList(pubResourcesClass);
    }

    @Override
    public AjaxResult deleteResourcesClass(Long id) {
        PubResourcesClass pubResourcesClass = new PubResourcesClass();
        pubResourcesClass.setAncestors(String.valueOf(id));
        List<PubResourcesClass> pubResourcesClasses = pubResourcesClassMapper.selectPubResourcesClassList(pubResourcesClass);
        if (pubResourcesClasses != null && !pubResourcesClasses.isEmpty()) {
            return AjaxResult.error("存在子目录,不允许删除!");
        }
        return AjaxResult.success(this.removeById(id));
    }

    @Override
    public AjaxResult addResourcesClass(PubResourcesClass pubResourcesClass) {
        if (pubResourcesClass == null || pubResourcesClass.getParentId() == null) {
            return AjaxResult.error("添加失败，请选择父对象！");
        }
        pubResourcesClass.setPath(pubResourcesClass.getName());
        pubResourcesClass.setDirPath(pubResourcesClass.getPath());
        Long rootId = 0L;
        if (!rootId.equals(pubResourcesClass.getParentId())) {
            PubResourcesClass parentResourcesClass = this.getById(pubResourcesClass.getParentId());
            pubResourcesClass.setParentName(parentResourcesClass.getName());
            pubResourcesClass.setAncestors(parentResourcesClass.getAncestors() + "," + parentResourcesClass.getId());
            pubResourcesClass.setDirPath(parentResourcesClass.getDirPath() + "/" + pubResourcesClass.getPath());
        }
        return AjaxResult.success(this.saveOrUpdate(pubResourcesClass));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public AjaxResult updateResourcesClass(PubResourcesClass pubResourcesClass) {
        if (pubResourcesClass == null) {
            return AjaxResult.error("修改失败，对象为空！");
        }
        if (pubResourcesClass.getId() == null) {
            return AjaxResult.error("修改失败，id为空值！");
        }
        if (pubResourcesClass.getParentId() == null) {
            return AjaxResult.error("修改失败，parentId为空值！");
        }
        PubResourcesClass oldEntity = this.getById(pubResourcesClass.getId());
        if (oldEntity == null) {
            return AjaxResult.error("修改失败，id错误未找到对象！");
        }
        Long parentId = pubResourcesClass.getParentId();
        if (!parentId.equals(oldEntity.getParentId())) {
            //父parentId有变化，需判断有效性并更新子对象ancestors
            if (parentId.equals(pubResourcesClass.getId())) {
                return AjaxResult.error("修改失败，上级对象不能是自己!");
            }
            //根节点的ancestors为0
            String newAncestors = "0";
            //非根节点计算ancestors
            if (!parentId.equals(0L)) {
                PubResourcesClass newParentEntity = this.getById(parentId);
                if (newParentEntity != null && newParentEntity.getAncestors() != null && newParentEntity.getAncestors().contains(oldEntity.getAncestors() + ",")) {
                    return AjaxResult.error("修改失败，父子对象不能循环设置!");
                }
                newAncestors = newParentEntity.getAncestors() + "," + newParentEntity.getId();
            }
            String oldAncestors = oldEntity.getAncestors();
            pubResourcesClass.setAncestors(newAncestors);
            this.updateChildren(oldEntity.getId(), newAncestors, oldAncestors);
        }
        return AjaxResult.success(this.updateById(pubResourcesClass));
    }

    /**
     * 修改子元素关系
     *
     * @param id           被修改的ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    private void updateChildren(Long id, String newAncestors, String oldAncestors) {
        PubResourcesClass pubResourcesClass = new PubResourcesClass();
        pubResourcesClass.setAncestors(String.valueOf(id));
        List<PubResourcesClass> children = pubResourcesClassMapper.selectPubResourcesClassList(pubResourcesClass);
        for (PubResourcesClass child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            this.updateBatchById(children);
        }
    }

    @Override
    public List<TreeSelect> buildTemplateClassTreeSelect(List<PubResourcesClass> pubResourcesClasses) {
        TreeBuilder<PubResourcesClass, TreeSelect> treeBuilder = new TreeBuilder<>();
        return treeBuilder.buildTreeSelect(pubResourcesClasses, PubResourcesClass::getId, o -> o.toTreeSelect(o));
    }
}
